<template>
  <div class="main-box">
    <TreeFilter
      label="name"
      id="_id"
      title="角色"
      :data="treeFilterData"
      :default-value="initParam.condition.roleId"
      @change="changeTreeFilter"
    />
    <div class="table-box">
      <ProTable
        ref="proTable"
        :indent="20"
        :highlight-current-row="true"
        row-key="_id"
        :expand-all="true"
        :columns="columns"
        :tool-button="false"
        :request-api="getTableList"
        :request-auto="false"
        :pagination="false"
        :init-param="initParam"
      >
        <!-- 表格 header 按钮 -->
        <template #tableHeader>
          <el-button type="primary" :disabled="!initParam.condition.roleId" :icon="CirclePlus" @click="settingRole()">
            新增权限
          </el-button>
        </template>
        <!-- 表格操作 -->
        <template #operation="scope">
          <el-button type="primary" link :icon="Delete" @click="deleteAccount(scope.row)">删除</el-button>
        </template>
      </ProTable>
      <CommonDialogSelect
        title="选择权限"
        :columns="roleColumns"
        :request-api="getAuthData"
        ref="drawerRef"
        :expand-all="false"
        @change="onRoleSelect"
      />
    </div>
  </div>
</template>

<script setup lang="tsx" name="useProTable">
import { ref, reactive, onMounted } from "vue";
import { MenuButton, RoleAuth } from "@/api/types/base";
import ProTable from "@/components/ProTable/index.vue";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { useHandleData } from "@/hooks/useHandleData";
import { Delete, CirclePlus } from "@element-plus/icons-vue";
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
import apiService from "@/api/services/apiService";
import CommonDialogSelect from "@/components/SelectFilter/common-dialog-select.vue";
import { arrayToTree, findFromTree } from "@/utils";
// ProTable 实例
const proTable = ref<ProTableInstance>();

// 如果表格需要初始化请求参数，直接定义传给 ProTable (之后每次请求都会自动带上该参数，此参数更改之后也会一直带上，改变此参数会自动刷新表格数据)
const initParam = reactive({
  condition: { roleId: "" }
});

onMounted(() => {
  getTreeList();
});

// 如果你想在请求之前对当前请求参数做一些操作，可以自定义如下函数：params 为当前所有的请求参数（包括分页），最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
const getTableList = async (params: any) => {
  params.options = {
    tree: { id: "businessId", pid: "pBusinessId", children: "children" }
  };
  return apiService.findTree<RoleAuth>("roleAuth", params.condition, params.options);
};

const treeFilterData = ref<any>([]);
const getTreeList = async () => {
  const { data } = await apiService.findTree("roles");
  treeFilterData.value = data;
  initParam.condition.roleId = treeFilterData.value[0]._id;
};

// 树形筛选切换
const changeTreeFilter = (val: string) => {
  proTable.value!.pageable.pageNum = 1;
  initParam.condition.roleId = val;
};

// 获取权限数据
const getAuthData = async (params: any) => {
  return new Promise(async resolve => {
    let result: RoleAuth[] = [];
    let condition = {};
    if (params.condition && params.condition.businessName) {
      condition = { like: { title: params.condition.businessName } };
    }
    let menuList = await apiService.find<Menu.MenuOptions[]>("menus", condition, { sort: { sort: 1 } });
    let buttonList = await apiService.find<MenuButton[]>("menuButtons");
    menuList.data.forEach(menu => {
      result.push({
        _id: menu._id,
        authType: "MENU",
        businessId: menu._id,
        businessName: menu.title,
        pBusinessId: menu.pid
      });
    });
    buttonList.data.forEach(button => {
      result.push({
        _id: button._id,
        authType: "BUTTON",
        businessId: button._id,
        businessName: button.name,
        businessKey: button.key,
        pBusinessId: button.menuId
      });
    });
    resolve({ data: arrayToTree(result, { id: "businessId", pid: "pBusinessId", children: "children" }) });
  });
};

// 表格配置项
const columns = reactive<ColumnProps<RoleAuth>[]>([
  { type: "index", label: " ", width: 60 },
  { prop: "businessName", label: "名称" },
  {
    prop: "authType",
    label: "权限类型",
    enum: () => apiService.findClassify("AUTH_TYPE"),
    fieldNames: { label: "name", value: "value" },
    search: { el: "select", props: { filterable: true } }
  },
  { prop: "operation", label: "操作", fixed: "right", width: 240 }
]);

// 表格配置项
const roleColumns: ColumnProps[] = [
  { type: "selection", fixed: "left", width: 70 },
  { prop: "businessName", label: "名称", align: "left", search: { el: "input" } },
  {
    prop: "authType",
    label: "类型",
    enum: () => apiService.findClassify("AUTH_TYPE"),
    fieldNames: { label: "name", value: "value" }
  }
];

const drawerRef = ref<InstanceType<typeof CommonDialogSelect> | null>(null);
const settingRole = () => {
  drawerRef.value?.openDialog();
};

const onRoleSelect = async (rows: any) => {
  let selectAuth: RoleAuth[] = [];
  rows.forEach(item => {
    if (!findFromTree(proTable.value?.tableData, item.businessId, "businessId", "children")) {
      selectAuth.push({
        roleId: initParam.condition.roleId,
        businessId: item.businessId,
        businessName: item.businessName,
        pBusinessId: item.pBusinessId,
        authType: item.authType
      });
    }
  });
  if (selectAuth.length > 0) {
    await apiService.saveList("roleAuth", selectAuth);
    proTable.value?.getTableList();
  }
};

// 删除信息
const deleteAccount = async (params: RoleAuth) => {
  await useHandleData(apiService.deleteById, "roleAuth", params._id, `删除【${params.businessName}】`);
  proTable.value?.getTableList();
};
</script>
